package com.xxx.blog.service.impl;

import com.github.pagehelper.PageHelper;
import com.xxx.blog.domain.ArticleType;
import com.xxx.blog.mapper.ArticleTypeMapper;
import com.xxx.blog.query.ArticleTypeQuery;
import com.xxx.blog.service.IArticleTypeService;
import com.xxx.blog.vo.ArticleTypeVo;
import org.springframework.cache.annotation.Cacheable;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.util.*;

@Service//
public class ArticleTypeServiceImpl implements IArticleTypeService {
    @Autowired
    private ArticleTypeMapper articleTypeMapper;
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public List<ArticleType> findAll() {
        return articleTypeMapper.findAll();
    }

    @Override
    public ArticleType findOne(Long id) {
        return articleTypeMapper.findOne(id);
    }

    @Override
    public List<ArticleType> queryPage(ArticleTypeQuery articleTypeQuery) {
        PageHelper.startPage(articleTypeQuery.getCurrentPage(), articleTypeQuery.getPageSize());

        return articleTypeMapper.queryPage(articleTypeQuery);
    }

    @Override
    @CacheEvict(cacheNames = "articleType", key = "'typeTree'")//''要加,这是spring的spel表达式的要求!
    public void addArticleType(ArticleType articleType) {
        // redisTemplate.delete("typeTree");// 第一次删除
        articleTypeMapper.addArticleType(articleType);

        // try {
        //     Thread.sleep(1000);
        // } catch (InterruptedException e) {
        //     throw new RuntimeException(e);
        // }
        // redisTemplate.delete("typeTree");// 第二次删除
    }

    @Override
    @Transactional
    @CacheEvict(cacheNames = "articleType", key = "'typeTree'")//''要加,这是spring的spel表达式的要求!
    public void updateArticleType(ArticleType articleType) {
        articleTypeMapper.updateArticleType(articleType);
    }

    // alt shif p
    @Override
    @Transactional
    @CacheEvict(cacheNames = "articleType", key = "'typeTree'")//''要加,这是spring的spel表达式的要求!
    public void deleteArticleType(Long id) {
        articleTypeMapper.deleteArticleType(id);
    }

    @Override
    @Transactional
    @CacheEvict(cacheNames = "articleType", key = "'typeTree'")
    public void batchArticleTypes(Long[] ids) {
        articleTypeMapper.batchArticleTypes(ids);
    }

    @Override
    @Cacheable(cacheNames = "articleType", key = "'typeTree'")//''要加,这是spring的spel表达式的要求!
    public List<ArticleType> getTypeTree() {
        // List<ArticleType> typeList = (List<ArticleType>) redisTemplate.boundValueOps("typeTree").get();
        // if (typeList != null) {
        //     System.out.println("数据来自redis");
        //     return typeList;
        // }
        // System.out.println("数据来自mysql");
        // typeList = this.getTypeTrees(id);
        // redisTemplate.boundValueOps("typeTree").set(typeList);

        return this.getTypeTrees();
    }

    @Override
    public List<ArticleTypeVo> getArticleTypeStatistics() {
        return articleTypeMapper.getArticleTypeStatistics();
    }

    @NotNull
    public List<ArticleType> getTypeTrees() {

        List<ArticleType> typeTree = new ArrayList<ArticleType>();//类型树,本质是一个集合

        //找到所有的类型,判断每一个类型的parentId是否是null
        //如果是null,说明这个类型是一级类型,就添加到类型树(集合)
        //如果不是null,说明这个类型是子级类型,找到子类型的一级类型,拿到一级类型的子类型集合,把这个子级类型添加到这个子类型集合
        List<ArticleType> articleTypeList = articleTypeMapper.findAll();

        Map<Long,ArticleType> map = new HashMap<>();//缓存好做对比
        for (ArticleType articleType : articleTypeList) {
            map.put(articleType.getId(), articleType);
        }

        for (ArticleType articleType : articleTypeList) {
            Long parentId = articleType.getParentId();

            if (parentId==null){
                typeTree.add(articleType);//所有一级,所有的爹
            }else {
                //根据id找到一个类型,映射map<id,articleType>缺啥补啥
                ArticleType articleTypeParent = map.get(parentId);//找到这个儿子对应的爹,
                articleTypeParent.getChildren().add(articleType);//所有的一级,所有的爹装它的儿子们
            }
        }

        return typeTree;//一个
    }
}
